手写属性访问函数 
js
/**
 * 安全访问嵌套对象属性,支持数组索引
 * @param {Object} obj - 目标对象
 * @param {string} path - 属性路径,例如 'a.b[0].c'
 * @param {any} [defaultValue=undefined] - 默认值
 * @returns {any} 属性值或默认值
 */
function getProperty(obj, path, defaultValue) {
  // 1. 路径解析:拆分成属性名和数组索引
  const segments = [];
  const regex = /([^\.\[\]]+)|\[(\d+)\]/g;
  let match;
  
  while ((match = regex.exec(path)) !== null) {
    if (match[1]) { // 捕获属性名
      segments.push(match[1]);
    } else if (match[2]) { // 捕获数组索引
      segments.push(parseInt(match[2], 10));
    }
  }
  // 2. 逐级访问属性
  let current = obj;
  for (const segment of segments) {
    if (current === null || current === undefined) break;
    current = current[segment];
  }
  // 3. 返回最终值或默认值
  return current !== undefined ? current : defaultValue;
}
// 示例测试
const obj = {
  user: {
    name: 'John',
    hobbies: [
      { title: 'Coding', tags: ['js', 'node'] },
      { title: 'Gaming' }
    ],
    'special.property': 'Secret' // 包含特殊字符的属性
  }
};
// 测试用例
console.log(getProperty(obj, 'user.name')); // 'John'
console.log(getProperty(obj, 'user.hobbies[0].tags[1]')); // 'node'
console.log(getProperty(obj, 'user.hobbies[1].title')); // 'Gaming'
console.log(getProperty(obj, 'user.hobbies[3]', 'Not Found')); // 'Not Found'
console.log(getProperty(obj, 'user["special.property"]')); // undefined(需特殊处理)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50